<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      // 手写Promise
      var MyPromise = (function (window) {
        //1.三个状态会多次使用到
        const PENDING = "pending"; //等待
        const RESOLVED = "resolved"; //成功
        const REJECTED = "rejected"; //失败
        // 2.返回一个class，可以实例化
        return class MyPromise {
          // 3.构造函数参数为回调
          constructor(fn) {
            this.status = PENDING; //4、默认状态等待
            this.value = undefined; //5、成功返回值
            this.reason = undefined; //6、失败返回值
            // 7、声明成功的方法
            const resolved = (value) => {
              // 9、状态为等待时修改
              if (this.status === PENDING) {
                this.status = RESOLVED; //10、状态为成功
                this.value = value; //11、保存成功的数据
              }
            };
            // 8、声明失败的方法
            const reject = (value) => {
              if (this.status === PENDING) {
                this.status = REJECTED; //12、状态为失败
                this.reason = value; //13、保存失败的数据
              }
            };
            // 同步代码的错误处理要使用try catch
            try {
              fn(resolved, reject);
            } catch (error) {
              reject(error);
            }
          }
          then(onFulfilled, onRejected) {
            if (this.status === RESOLVED) {
              onFulfilled && onFulfilled(this.value);
            }
            if (this.status === REJECTED) {
              onRejected && onRejected(this.reason);
            }
          }
        };
      })(window);
      //使用
      new Promise((resolve, reject) => {
        setTimeout(() => {
          if (Math.random() > 0.5) {
            resolve("成功");
          } else {
            reject("失败");
          }
        });
      })
        .then(
          (res) => {
            console.log("then参数一", res);
          },
          (err) => {
            console.log("then参数二", err);
          }
        )
        .catch((err) => {
          console.log("catch方法", err);
        })
        .finally(() => {
          console.log("无论成功与否都会执行");
        });
    </script>
  </body>
</html>
